package pe.tnova.generic.structure.project.springmvc.generic;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;

import pe.tnova.generic.structure.project.springmvc.soruce.SourceProjectCore;
import pe.tnova.generic.structure.project.springmvc.util.ConstantesTNOVA;
import pe.tnova.generic.structure.project.springmvc.util.PluginUtil;

public class DAOBaseGeneric {

	private String strPackageBase;
	private IPackageFragment packDAOBase;
	private ICompilationUnit[] compilationUnit;
//	private SourceProjectCore sourceProjectCore;
	public DAOBaseGeneric(SourceProjectCore sourceProjectCore, String strPackageBase, IPackageFragment packDAOBase, ICompilationUnit[] compilationUnit) {
		this.strPackageBase = strPackageBase;
		this.packDAOBase = packDAOBase;
		this.compilationUnit = compilationUnit;
//		this.sourceProjectCore = sourceProjectCore;
	}

	public void generar() throws JavaModelException {
		ICompilationUnit claseDAOBASE = null;
		String strEntidadNombre = null ;
		for (ICompilationUnit entidad : compilationUnit) {
			strEntidadNombre = PluginUtil.getNameFile(entidad.getElementName());
			claseDAOBASE = packDAOBase.createCompilationUnit(
					strEntidadNombre + ConstantesTNOVA.CLASS_DAO_BASE + ConstantesTNOVA.EXTENSION_JAVA, 
					generarCodigoFuente(strEntidadNombre, strPackageBase+ ConstantesTNOVA.DONT+ ConstantesTNOVA.PACK_DAO_BASE), 
					true, null);

			IType claseDB = claseDAOBASE.getTypes()[0];
			IType clase = entidad.getTypes()[0];
			
			System.out.println("clase:"+clase.getElementName());
			
			String strMetododsPorInterfaz = "" , strMetododsPorEntidad , strMetodoFiltradoGeneral = "";
			ITypeHierarchy typeHier= clase.newSupertypeHierarchy(null);
			IType[] superInterfaces= typeHier.getAllInterfaces();
			IType interfazEntidad = null;
			for (IType iType2 : superInterfaces) {
				if(iType2.getElementName().equals(ConstantesTNOVA.CLASS_ENTIDAD)){
					interfazEntidad = iType2;
					strMetododsPorInterfaz = generarCamposPorIEntidad(clase,interfazEntidad);					
				}
			}		
			
			claseDB.createMethod(strMetododsPorInterfaz, null, false, null);	
			
		}		
	}
	
	private String generarCodigoFuente(String nameEntidad, String strRuta) {
		StringBuilder buffer = new StringBuilder();
		buffer.append("package " + strRuta + ";");
		buffer.append(ConstantesTNOVA.EN);
		buffer.append("import java.util.HashMap;"+ConstantesTNOVA.EN);
		buffer.append("import java.util.List;"+ConstantesTNOVA.EN);
		buffer.append("import java.util.Map;"+ConstantesTNOVA.EN);
		buffer.append("import java.util.Map.Entry;"+ConstantesTNOVA.EN);
		buffer.append("import javax.persistence.Query;"+ConstantesTNOVA.EN);
		buffer.append("import java.util.Date;"+ConstantesTNOVA.EN);
		buffer.append("import pe.tnova.core.db.DAOBase;"+ConstantesTNOVA.EN);
		buffer.append("import "+ strPackageBase + ConstantesTNOVA.DONT+ ConstantesTNOVA.CARPETA_DOMINIO+ ConstantesTNOVA.DONT+ nameEntidad+ ";"+ConstantesTNOVA.EN);
		buffer.append("import javax.persistence.EntityManager;"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.EN);
		buffer.append("public class " + nameEntidad + "DAOBase extends DAOBase {\n");		
		buffer.append(ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String STR_MENSAJE_SIN_REGISTROS_EXCEPTION = \"No hay registro.\";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String STR_MENSAJE_ERROR_EXCEPTION = \"Error en la conexion.\";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String SQL_ENTIDAD = \""+nameEntidad+"\";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String SQL_QUERY = \" select p from \" + SQL_ENTIDAD + \" p \";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String SQL_WHERE = \"where\";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String SQL_SUFIJO_ENTIDAD = \" p. \";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String SQL_MENOS = \" < \";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String SQL_MAS = \" > \";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET + "public static String SQL_QUERY_CONSTRUCTOR_ID = \" select new "+nameEntidad+"(p.id) from "+nameEntidad+" p \";"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET+"public " + nameEntidad + "DAOBase(EntityManager em) {"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET+ConstantesTNOVA.ET+"super(em);"+ConstantesTNOVA.EN);
		buffer.append(ConstantesTNOVA.ET+"}"+ConstantesTNOVA.EN);		
		buffer.append("}"+ConstantesTNOVA.EN);	
		System.out.println(buffer.toString());
		return buffer.toString();
	}

	private String generarCamposPorIEntidad(IType clase,IType interfazEntidad) throws JavaModelException {
		System.out.println("generarPorInterfazEntidad:");
		String strnombreCampo = null ;
		StringBuffer buffer = new StringBuffer();
		for (IMethod metodos : interfazEntidad.getMethods()) {
			System.out.println(metodos.getElementName());
			strnombreCampo = PluginUtil.getCamporDesdeMetodoGET(metodos.getElementName());
			System.out.println(strnombreCampo);
			if(permitido(strnombreCampo)){
				IField iFieldCampo = clase.getField(strnombreCampo);
				System.out.println("exists:"+iFieldCampo.exists());
				if(iFieldCampo.exists()){
//					buffer.append(generarMetodosPorTipoDato(clase,strnombreCampo,iFieldCampo));
				}
			}
		}
		return buffer.toString();
	}
	
//	private String generarMetodosPorTipoDato(IType clase, String strnombreCampo, IField iFieldCampo) throws JavaModelException {
//		StringBuilder buffer = new StringBuilder();		
//		
//		String tipoParametro = PluginUtil.getTipoparamtroInstanceOf(iFieldCampo.getTypeSignature());
//		String whereClause = "";
//		String pametrosWhere  = "";
//		String nameMethodBy  = "By";
//		String mapParameters = "";
//		
//		pametrosWhere = tipoParametro+" "+strnombreCampo;
//		whereClause ="where p."+strnombreCampo+" = :"+strnombreCampo+" ";
//		mapParameters = "map.put(\""+strnombreCampo+"\", "+strnombreCampo+"); ";
//
//		if (tipoParametro.equals(ConstantesTNOVA.TYPE_ATRIBUTTE_STRING)) {
//			nameMethodBy="Like";
//			pametrosWhere = tipoParametro+" "+strnombreCampo;
//			whereClause ="where p."+strnombreCampo+" like :"+strnombreCampo+" ";
//			mapParameters = "map.put(\""+strnombreCampo+"\",\"%\"+ "+strnombreCampo+"+\"%\"); ";
//		}
//		
//		if (tipoParametro.equals(ConstantesTNOVA.TYPE_ATRIBUTTE_DATE)) {
//			nameMethodBy="Between";
//			pametrosWhere = tipoParametro+" "+strnombreCampo +"Inicio , " +tipoParametro+" "+strnombreCampo+"Fin";
//			whereClause ="where p."+strnombreCampo+" between :"+strnombreCampo+"Inicio and "+strnombreCampo+"Fin ";
//			mapParameters = "map.put(\""+strnombreCampo+"Inicio\", "+strnombreCampo+"Inicio);\n  ";
//			mapParameters += "map.put(\""+strnombreCampo+"Fin\", "+strnombreCampo+"Fin); ";
//		}
//		
//		buffer.append(ConstantesTNOVA.ET +"public List<"+clase.getElementName()+"> getLista"+clase.getElementName()+nameMethodBy+ PluginUtil.capitalizarPrimerCaracter(strnombreCampo)+"("+pametrosWhere+", String campoOrder, String order) throws Exception{"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"String query = \" select p from "+clase.getElementName()+" p "+whereClause+" \" ;"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"if( (campoOrder!=null) && (!campoOrder.equals(\"\")) && (campoOrder.length()>0) ) {"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +ConstantesTNOVA.ET +"query += \" order by \" + campoOrder + \" \"+ order ;"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"}"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"query += \" ; \"; "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"Map<String, Object> map = getNewMap(); "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +mapParameters+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"try { "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + ConstantesTNOVA.ET +"List<"+clase.getElementName()+"> p = getQuery( query ,map); "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + ConstantesTNOVA.ET +"if (p != null) { "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + ConstantesTNOVA.ET +ConstantesTNOVA.ET +"return p; "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + ConstantesTNOVA.ET +"} else { "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + ConstantesTNOVA.ET +"throw new "+clase.getElementName()+"Exception(STR_MENSAJE_SIN_REGISTROS_EXCEPTION); "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + ConstantesTNOVA.ET +"} "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + "} catch (Exception e) { "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + ConstantesTNOVA.ET + "throw new "+clase.getElementName()+"Exception(STR_MENSAJE_ERROR_EXCEPTION); "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET + "} "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET + "} "+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.EN);
//		
//		buffer.append(ConstantesTNOVA.ET + "public Integer count"+clase.getElementName()+nameMethodBy+ PluginUtil.capitalizarPrimerCaracter(strnombreCampo)+"("+pametrosWhere+") throws Exception{"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"String query = \" select count(p) from "+clase.getElementName()+" p "+whereClause+"; \" ;"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"Map map = getNewMap();"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +mapParameters+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"try {"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +ConstantesTNOVA.ET +"Integer p = (Integer) getSingleQuery(query, map);"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +ConstantesTNOVA.ET +"return p;"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"} catch (Exception e) {"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +ConstantesTNOVA.ET +"throw new "+clase.getElementName()+"Exception(STR_MENSAJE_ERROR_EXCEPTION);"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +ConstantesTNOVA.ET +"}"+ConstantesTNOVA.EN);
//		buffer.append(ConstantesTNOVA.ET +"}"+ConstantesTNOVA.EN);
//    
//		return buffer.toString();
//	}
	
	private boolean permitido(String strnombreCampo) {
		if(strnombreCampo.equals("id")){
			return false;
		}
		return true;
	}
}
